home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_02_04
/
2n04075a
< prev
next >
Wrap
Text File
|
1991-02-16
|
4KB
|
177 lines
/* LISTING 1 (inc_sfht.c)
Make additional entries available in the System File
Handle Table. Use this in lieu of forcing the user to
add a FILES= statement in the config.sys and re-boot.
To build an executable:
cl -AL inc_sfht.c (MSC 5.x NOTE: Large model.)
*/
#include <stdio.h>
#include <malloc.h>
#include <dos.h>
// NOTE: must pack structures on byte alignment
#pragma pack(1)
// --- see the article for description of these elements
typedef struct list_of_lists
{
void far *dcb_head, far *handle_sft, far *clock;
void far *console;
unsigned max_sector;
void far *cache, far *cur_dir, far *fcb_sft;
unsigned unknown;
unsigned char drive_cnt, lastdrive;
} LOL, far *LOL_PTR;
// --- see the article for description of these elements
typedef struct system_file_table_header
{
void far *next;
unsigned count;
} SFTH, far *SFTH_PTR;
#define SFTH_SIZE sizeof(SFTH)
// prototypes
short open_files(void), add_system_handles(short);
short find_size(void *);
void remove_added_handles(void), close_files(void);
// place to hold the original end-of-list header
static SFTH_PTR old_end_of_list = (SFTH_PTR)0;
// for the testing file structures
FILE *fid_array[20];
main()
{
printf("opened %d before expansion\n", open_files());
close_files();
add_system_handles(5);
printf("opened %d after expansion\n", open_files());
close_files();
remove_added_handles();
printf("opened %d after reset\n", open_files());
close_files();
}
short open_files()
{
short i;
for(i = 0; i < 20; i++)
if( (fid_array[i] = fopen("nul", "wt")) == NULL )
break;
return(i);
}
void close_files()
{
short i = 0;
while( fid_array[i] != (FILE *)NULL )
fclose(fid_array[i++]);
}
short add_system_handles( short new_entries )
{
union REGS inregs, outregs;
struct SREGS sregs;
LOL_PTR lol;
SFTH_PTR sfth, new_block;
char *sft;
short infoblk_size;
if( old_end_of_list != (char *)NULL )
return(-1);
// get the list of list address
inregs.h.ah = 0x52;
int86x(0x21, &inregs, &outregs, &sregs);
FP_SEG(lol) = sregs.es;
FP_OFF(lol) = outregs.x.bx;
// get the 1st table header address
sfth = lol->handle_sft;
// get the actual table address
sft = (char *)sfth + SFTH_SIZE;
// find the size of a single file information block
infoblk_size = find_size(sft);
if( infoblk_size == 0 )
return(-2);
// find the last node in the SFHT
while( FP_OFF(sfth->next) != 0xffff )
sfth = sfth->next;
// save the old end address & chain on some more entries
new_block = (SFTH_PTR)calloc(new_entries,
infoblk_size + SFTH_SIZE);
if( new_block == (SFTH_PTR)0 )
return(0);
old_end_of_list = sfth;
// init the new entry header
FP_OFF(new_block->next) = 0xffff;
new_block->count = new_entries;
// chain it in and return success
sfth->next = new_block;
return(1);
}
void remove_added_handles()
{
// if haven't allocated, don't free
if( old_end_of_list == (SFTH_PTR)0 )
return;
// free the allocated memory, make the header indicate the
// end of the list, & clear the static pointer
free(old_end_of_list->next);
FP_OFF(old_end_of_list->next) = 0xffff;
old_end_of_list = (SFTH_PTR)0;
}
short find_size( char *ft_ptr )
{
char *ch_ptr, *aux_ptr;
short i;
// search for the string "AUX" (1st info blk entry)
ch_ptr = ft_ptr;
for(i = 0; i < 100; i++ )
{
if( strncmp(ch_ptr, "AUX", 3) == 0 )
{
aux_ptr = ch_ptr;
break;
}
else
ch_ptr++;
}
// if not found return error
if( i == 100 )
return(0);
// now search for "CON" (2nd info blk entry)
for(i = 0; i < 100; i++ )
{
if( strncmp(ch_ptr, "CON", 3) == 0 )
break;
else
ch_ptr++;
}
// if not found return error
if( i == 100 )
return(0);
// return the difference (i.e. size of an info blk)
return(ch_ptr - aux_ptr);
}